﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Waker.Common;
using System.Text.RegularExpressions;
using Waker.APIs.ADS;
using System.Runtime.InteropServices;
using Waker.Entitys;

namespace Waker.Devices
{
    public partial class FormDeviceEdit : Base.FormBasePop
    {
        DataTable _DtSource;
        ADSHalDataStruct.ADS_CommunicationParameter m_comm = new ADSHalDataStruct.ADS_CommunicationParameter();
        public FormDeviceEdit(string id)
        {
            InitializeComponent();
            this.Text += string.IsNullOrEmpty(id) ? "添加" : "修改";
            _DtSource = new BAL.BAL_Device().GetDeviceByID(id);
        }

        private void FormDeviceEdit_Load(object sender, EventArgs e)
        {
            if (_DtSource.Rows.Count < 1)
            {
                this.BindingContext[_DtSource].AddNew();
                txtComAdapter_Addr.Text = "192.168.0.200";
                speComAdapter_Port.Value = 65000;
                txtComAdapter_pwd.Text = "0";
                this.BindingContext[_DtSource].EndCurrentEdit();
            }
            else
            {
                ControlUtil.BindData(this.Controls, _DtSource);
                icbDevice_Type.EditValue = Convert.ToInt32(_DtSource.Rows[0]["Device_Type"]);
            } 
        }
        /// <summary>
        /// 测试连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void simpleButton1_Click(object sender, EventArgs e)
        {
            TestConnection();
        }
        protected override void FormSave()
        {
            if (!TestConnection())
                return;

            ADSHalDataStruct.ADS_ControllerInformation ctrlInfo = new ADSHalDataStruct.ADS_ControllerInformation();
            int res = ADSHalAPI.ADS_GetControllerInformation(ref Session._ADS_Comadapter, ref m_comm, ref ctrlInfo);
            if (res != (int)ADSHalConstant.ADS_ResultCode.ADS_RC_SUCCESS)
            {
                lblStatus.Text = "未连接";
                ADSHelp.PromptResult(res, true);
                return;
            }

            lblStatus.Text = "已经连接";
            //sb.Append(ctrlInfo.description);
            var Physics_ID = ctrlInfo.deviceID.ToString();
            //textBox4.Text = ctrlInfo.deviceID.ToString();
            //textBox5.Text = sb.ToString();
            //textBox6.Text = ctrlInfo.firmwareVersion.ToString();
            //textBox7.Text = sb.ToString();
            //textBox8.Text = ctrlInfo.maxCardHolderCount.ToString();
            icbDevice_Type.EditValue = Convert.ToInt32(ctrlInfo.productType);
            if (icbDevice_Type.EditValue == DBNull.Value || icbDevice_Type.EditValue == null)
            {
                base.errorPop.SetError(icbDevice_Type, "请选择设备类型");
                return;
            }
            var bal = new BAL.BAL_Device();
            if (_DtSource.Rows[0]["Device_ID"] == DBNull.Value)
            {
                if (!bal.CheckDevice(txtComAdapter_Addr.Text.Trim(), Convert.ToInt32(speComAdapter_Port.Value), Physics_ID))
                {
                    UI.ShowError("设备已经存在,请确认后重试");
                    return;
                }
            }
            var listSubs = SearchSubs();
            if (listSubs == null)
            {
                UI.ShowError("检索子设备失败,请稍后重试");
                return;
            }
            var isok = bal.SaveDevice(
                _DtSource.Rows[0]["Device_ID"] == DBNull.Value ? string.Empty : _DtSource.Rows[0]["Device_ID"].ToString()
                , Physics_ID
                , txtDevice_Name.Text.Trim()
                , icbDevice_Type.EditValue.ToString()
                , txtDevice_Desc.Text
                , _DtSource.Rows[0]["ComAdapter_ID"] == DBNull.Value ? string.Empty : _DtSource.Rows[0]["ComAdapter_ID"].ToString()
                , txtComAdapter_Addr.Text.Trim()
                , speComAdapter_Port.Value.ToString()
                , txtComAdapter_pwd.Text
                , listSubs
                );
            if (isok)
            {
                UI.ShowInfo("保存成功");
                this.DialogResult = DialogResult.OK;
            }
            else
            {
                UI.ShowError("保存失败");
                return;
            }

        }
        bool TestConnection()
        {
            base.errorPop.ClearErrors();
            if (string.IsNullOrEmpty(txtDevice_Name.Text))
            {
                base.errorPop.SetError(txtDevice_Name, "设备名称不能为空");
                return false;
            }

            if (string.IsNullOrEmpty(txtComAdapter_Addr.Text) || !IPHelper.CheckIPAddr(txtComAdapter_Addr.Text))
            {
                base.errorPop.SetError(txtComAdapter_Addr, "设备IP格式不正确");
                return false;
            }
            if (speComAdapter_Port.Value < 0 || speComAdapter_Port.Value > 65535)
            {
                base.errorPop.SetError(speComAdapter_Port, "端口超出范围");
                return false;
            }

            if (!string.IsNullOrEmpty(txtComAdapter_pwd.Text))
            {
                int pwd = -1;
                if (!int.TryParse(txtComAdapter_pwd.Text, out pwd) || pwd < 0)
                {
                    base.errorPop.SetError(txtComAdapter_pwd, "密码必须为数字,可以为空");
                    return false;
                }
            }
            // 连接
            m_comm.deviceAddr = ADSHelp.IP2Int(txtComAdapter_Addr.Text.Trim());
            m_comm.devicePort = (ushort)(Convert.ToUInt16(speComAdapter_Port.Value));
            m_comm.password = (ushort)(Convert.ToUInt16(txtComAdapter_pwd.Text));
            int iResult = ADSHalAPI.ADS_ConnectController(ref Session._ADS_Comadapter, ref m_comm);
            if (iResult != (int)ADSHalConstant.ADS_ResultCode.ADS_RC_SUCCESS)
            {
                lblStatus.Text = "未连接";
                ADSHelp.PromptResult(iResult, true);
                return false;
            }

            //IntPtr pt = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(typeof(ADSHalDataStruct.ADS_ControllerInformation)));
            //uint uRetCount = 0;
            //int iResult = ADSHalAPI.ADS_SearchController(ref m_comAdatpter, 1, 1, pt, 1, ref uRetCount);
            //if (iResult != (int)ADSHalConstant.ADS_ResultCode.ADS_RC_SUCCESS && uRetCount > 0)
            //{
            //    lblStatus.Text = "未连接";
            //    ADSHelp.PromptResult(iResult, true);
            //    return false;
            //}
            //var info = (ADSHalDataStruct.ADS_ControllerInformation)Marshal.PtrToStructure((IntPtr)((UInt32)pt + 0 * System.Runtime.InteropServices.Marshal.SizeOf(typeof(ADSHalDataStruct.ADS_ControllerInformation)))
            //        , typeof(ADSHalDataStruct.ADS_ControllerInformation));
            //icbDevice_Type.EditValue = info.productType;

            lblStatus.Text = "已经连接";
            return true;
        }
        bool DisConnection()
        {
            int iResult = ADSHalAPI.ADS_DisconnectController(ref Session._ADS_Comadapter, ref m_comm);
            ADSHelp.PromptResult(iResult, true);
            return iResult == (int)ADSHalConstant.ADS_ResultCode.ADS_RC_SUCCESS;
        }
        protected override void FormClose()
        {
            if (lblStatus.Text == "已连接")
                DisConnection();
            base.FormClose();
        }
        private List<ADSHalDataStruct.ADS_LogicSubDeviceInformation> SearchSubs()
        {
            uint m_uLogSudeviceCount = 0;
            /*
               搜索子设备流程：搜索物理子设备，搜索逻辑子设备
            */
            ADSHalDataStruct.ADS_PhysicalSubDeviceInformation[] physicalSubDevices = new ADSHalDataStruct.ADS_PhysicalSubDeviceInformation[64];

            uint uRetCount = 0;

            // 搜索物理子设备
            int iResult = ADSHalAPI.ADS_SearchPhysicalSubDevices(ref Session._ADS_Comadapter, ref m_comm, ref physicalSubDevices[0], 64, ref uRetCount);

            if (iResult != (int)ADSHalConstant.ADS_ResultCode.ADS_RC_SUCCESS)
            {
                ADSHelp.PromptResult(iResult, true);
                return null;
            }
            // 搜索逻辑子设备
            uint uLogicCount = 0;
            //var m_LogicSubDeviceInfo = new ADSHalDataStruct.ADS_LogicSubDeviceInformation[128];
            var m_LogicSubDeviceInfo = new List<ADSHalDataStruct.ADS_LogicSubDeviceInformation>();

            for (uint uIndex = 0; uIndex < uRetCount; uIndex++)
            {
                uLogicCount = 0;

                ADSHalDataStruct.ADS_PhysicalSubDeviceAddress phyphysicalAddr = new ADSHalDataStruct.ADS_PhysicalSubDeviceAddress();
                phyphysicalAddr.physicalSubDevAddr = physicalSubDevices[uIndex].subDevAddr;
                phyphysicalAddr.physicalSubDevID = physicalSubDevices[uIndex].physicalSubDevID;

                IntPtr[] ptArray = new IntPtr[1];
                ptArray[0] = System.Runtime.InteropServices.Marshal.AllocHGlobal(
                    System.Runtime.InteropServices.Marshal.SizeOf(typeof(ADSHalDataStruct.ADS_LogicSubDeviceInformation)) * 32);
                IntPtr pt = System.Runtime.InteropServices.Marshal.AllocHGlobal(
                    System.Runtime.InteropServices.Marshal.SizeOf(typeof(ADSHalDataStruct.ADS_LogicSubDeviceInformation)));
                System.Runtime.InteropServices.Marshal.Copy(ptArray, 0, pt, 1);

                iResult = ADSHalAPI.ADS_SearchLogicSubDevices(ref Session._ADS_Comadapter, ref m_comm, ref phyphysicalAddr, pt, 32, ref uLogicCount);

                for (int j = 0; j < uLogicCount; j++)
                {
                    //m_LogicSubDeviceInfo[j + m_uLogSudeviceCount] =
                    //(ADSHalDataStruct.ADS_LogicSubDeviceInformation)System.Runtime.InteropServices.Marshal.PtrToStructure((IntPtr)((UInt32)pt + j * System.Runtime.InteropServices.Marshal.SizeOf(typeof(ADSHalDataStruct.ADS_LogicSubDeviceInformation)))
                    //, typeof(ADSHalDataStruct.ADS_LogicSubDeviceInformation));
                    m_LogicSubDeviceInfo.Add(
                    (ADSHalDataStruct.ADS_LogicSubDeviceInformation)
                    System.Runtime.InteropServices.Marshal.PtrToStructure((IntPtr)((UInt32)pt + j * System.Runtime.InteropServices.Marshal.SizeOf(typeof(ADSHalDataStruct.ADS_LogicSubDeviceInformation)))
                    , typeof(ADSHalDataStruct.ADS_LogicSubDeviceInformation)));
                }
                System.Runtime.InteropServices.Marshal.FreeHGlobal(ptArray[0]);
                System.Runtime.InteropServices.Marshal.FreeHGlobal(pt);

                //for (uint i = 0; i < uLogicCount; i++)
                //{
                //    ListViewItem li = new ListViewItem();
                //    li.SubItems.Clear();
                //    li.SubItems[0].Text = (m_LogicSubDeviceInfo[i + m_uLogSudeviceCount].logicSubDeviceAddrNumber.physicalSubDevAddr).ToString();
                //    li.SubItems.Add(m_LogicSubDeviceInfo[i + m_uLogSudeviceCount].logicSubDeviceAddrNumber.logicSubDevNumber.ToString());
                //    li.SubItems.Add(ADSHelp.logicSubDeviceType[m_LogicSubDeviceInfo[i + m_uLogSudeviceCount].logicSubDeviceCategory - 1]);
                //    listView3.Items.Add(li);
                //}


                m_uLogSudeviceCount += uLogicCount;
            }
            return m_LogicSubDeviceInfo;
        }
    }
}
